/*
 * LagacyPreferenceSet.java
 *
 * Created on January 2, 2006, 12:40 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package net.jxta.myjxta.util.preferences;

import net.jxta.impl.shell.bin.Shell.Shell;
import net.jxta.logging.Logging;
import net.jxta.myjxta.dialog.filter.LegacyAnnounceFilter;
import net.jxta.myjxta.dialog.filter.PingPresenceFilter;
import net.jxta.myjxta.dialog.listener.ElizaListener;
import net.jxta.myjxta.dialog.listener.PounceListener;
import net.jxta.myjxta.dialog.listener.SoundListener;
import net.jxta.myjxta.dialog.listener.SpeechListener;
import net.jxta.myjxta.ui.Graph;
import net.jxta.myjxta.ui.ProxyHttp;
import net.jxta.myjxta.util.Env;
import net.jxta.myjxta.util.Group;
import net.jxta.myjxta.util.Resources;
import net.jxta.peergroup.PeerGroup;

import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author polo
 */
public class LegacyPreferenceSet extends PreferenceSet {
    private static final Logger LOG = Logger.getLogger(LegacyPreferenceSet.class.getName());


    private static final ResourceBundle STRINGS = Resources.getStrings();


    public static final String PREFERENCE_CHIME = "General.Legacy.Chime";
    public static final String PREFERENCE_PINGFILTER = "General.Legacy.PingFilter";
    public static final String PREFERENCE_FREETTS = "General.Legacy.Freetts";
    public static final String PREFERENCE_RECONFIGURE = "General.Legacy.Reconfigure";
    public static final String PREFERENCE_GRAPH = "General.Legacy.Graph";
    public static final String PREFERENCE_ELIZA = "General.Legacy.Eliza";
    public static final String PREFERENCE_SHELL = "General.Legacy.shell";
    public static final String PREFERENCE_POUNCELISTENER = "General.Legacy.PounceListener";
    public static final String PREFERENCE_PROXY_HTTP = "General.Legacy.ProxyHttp";


    private Hashtable<String, Method> methodTable = null;

    /**
     * The SoundListener object to use if enabling sound
     */
    private SoundListener sound = null;

    /**
     * The SpeechListner object to use if enabling freetts
     */
    private SpeechListener speech = null;
    private PounceListener pounce = null;
    private ElizaListener eliza = null;

    /**
     * The prefuse object to use if enabling Graph
     */
    private Graph graph = null;

    private Hashtable<String, Boolean> prefTable = null;

    /**
     * Creates a new instance of LagacyPreferenceSet
     */
    public LegacyPreferenceSet() {
        super();

        methodTable = new Hashtable<String, Method>();
        prefTable = new Hashtable<String, Boolean>();

        Class[] params = {boolean.class};
        try {
            methodTable.put(LegacyPreferenceSet.PREFERENCE_CHIME, this.getClass().getDeclaredMethod("enableChime", params));
            methodTable.put(LegacyPreferenceSet.PREFERENCE_ELIZA, this.getClass().getDeclaredMethod("enableElizaListener", params));
            methodTable.put(LegacyPreferenceSet.PREFERENCE_FREETTS, this.getClass().getDeclaredMethod("enableFreeTTS", params));
            methodTable.put(LegacyPreferenceSet.PREFERENCE_GRAPH, this.getClass().getDeclaredMethod("enableGraph", params));
            methodTable.put(LegacyPreferenceSet.PREFERENCE_PINGFILTER, this.getClass().getDeclaredMethod("enablePingFilter", params));
            methodTable.put(LegacyPreferenceSet.PREFERENCE_POUNCELISTENER, this.getClass().getDeclaredMethod("enablePounceListener", params));
            methodTable.put(LegacyPreferenceSet.PREFERENCE_RECONFIGURE, this.getClass().getDeclaredMethod("setReconfigure", params));
            methodTable.put(LegacyPreferenceSet.PREFERENCE_PROXY_HTTP, this.getClass().getDeclaredMethod("setProxyHttp", params));
            methodTable.put(LegacyPreferenceSet.PREFERENCE_SHELL, this.getClass().getDeclaredMethod("enableShell", params));

        } catch (SecurityException ex) {
            ex.printStackTrace();
        } catch (NoSuchMethodException ex) {
            ex.printStackTrace();
        }

        for (Iterator<String> itr = methodTable.keySet().iterator(); itr != null && itr.hasNext();) {
            prefTable.put(itr.next(), Boolean.FALSE);
        }

        this.sound = new SoundListener();
        this.speech = new SpeechListener();
        this.pounce = new PounceListener();
        this.eliza = new ElizaListener();


    }

    public void init() {

        for (Iterator<String> itr = prefTable.keySet().iterator(); itr != null && itr.hasNext();) {

            initEnable(itr.next());
        }
    }

    private void initEnable(String prefName) {
        boolean enable = Boolean.valueOf(getPreference(prefName));
        this.booleanPreferenceChanged(prefName, enable);

    }

    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void setReconfigure(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin setReconfigure(boolean)");
            LOG.fine("enable = " + enable);
        }

        Env.setReconfigure(enable);

        if (enable) {
//            try {
//                new net.jxta.ext.config.ui.Configurator(Env.getHome()).configure();
//            } catch (ConfiguratorException e) {
//                if (LOG.isEnabledFor(Level.SEVERE)) {
//                    LOG.error("Configuration UI messed up, please check error message!",e);
//                }
//            }
//
//            myjxta.setStatus(STRINGS.getString("status.prefs.reconfigure"));
        }

        LOG.fine("End   setReconfigure(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void setProxyHttp(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin setProxyHttp(boolean)");
            LOG.fine("enable = " + enable);
        }

        if (enable) {
            ProxyHttp pp = new ProxyHttp(PreferenceSet.myjxta);

            pp.setVisible(true);
        }

        LOG.fine("End setProxyHttp(boolean)");
    }

    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enableChime(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin enableChime(boolean)");
            LOG.fine("enable = " + enable);
        }

        if (enable) {
            if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
                LOG.fine("Calling " + myjxta.getClass() +
                        ".addListener  with parameter " +
                        sound.getClass().toString());
            }
            myjxta.addListener(this.sound);
        } else {
            if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
                LOG.fine("Calling " + myjxta.getClass() +
                        ".removeListener  with parameter " +
                        sound.getClass().toString());
            }
            myjxta.removeListener(this.sound);
        }

        LOG.fine("End   enableChime(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enableFreeTTS(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin enableFreeTTS(boolean)");
            LOG.fine("enable = " + enable);
        }

        if (enable) {
            myjxta.addListener(this.speech);
        } else {
            myjxta.removeListener(this.speech);
        }

        LOG.fine("End   enableFreeTTS(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enableLegacyFilter(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin enableLegacyFilter(boolean)");
            LOG.fine("enable = " + enable);
        }

        if (enable) {
            myjxta.addInboundFilter(new LegacyAnnounceFilter());
        } else {
            myjxta.removeInboundFilter(LegacyAnnounceFilter.class);
        }

        LOG.fine("End   enableLegacyFilter(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enablePingFilter(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin enablePingFilter(boolean)");
            LOG.fine("enable = " + enable);
        }

        if (enable) {
            myjxta.addInboundFilter(new PingPresenceFilter());
        } else {
            myjxta.removeInboundFilter(PingPresenceFilter.class);
        }

        LOG.fine("End   enablePingFilter(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enablePounceListener(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin enablePounceListener(boolean)");
            LOG.fine("enable = " + enable);
        }

        if (enable) {
            myjxta.addListener(this.pounce);
        } else {
            myjxta.removeListener(this.pounce);
        }

        LOG.fine("End   enablePounceListener(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enableElizaListener(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin enableElizaListener(boolean)");
            LOG.fine("enable = " + enable);
        }

        if (enable) {
            myjxta.addListener(this.eliza);
        } else {
            myjxta.removeListener(this.eliza);
        }

        LOG.fine("End   enableElizaListener(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enableGraph(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin enableGraph(boolean)");
            LOG.fine("enable = " + enable);
        }

        if (enable) { //nano: i know this is expensive but as long as we can not remove nodes cleanly we have to regenerate the graph ever time
            this.graph = new Graph(myjxta);
        } else {
            this.graph.dispose();
        }

        LOG.fine("End   enableGraph(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enableRosettaChat(boolean enable) {
        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("Begin enableRosettaChat(boolean)");
            LOG.fine("enable = " + enable);
        }


        LOG.fine("End   enableRosettaChat(boolean)");
    }


    @SuppressWarnings({"unused", "UnusedDeclaration"})
    private void enableShell(boolean enable) {
        LOG.fine("Begin enableShell(boolean)");
        boolean wasEnabled = false; //p.getBoolean(Prefs.SHELL_PREFERENCE_SET, false);

        if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
            LOG.fine("enable = " + enable);
            LOG.fine("wasEnabled = " + wasEnabled);
        }

        if (enable) {
            System.setProperty(Shell.JXTA_SHELL_EMBEDDED_KEY, "true");
            Group myGroup = myjxta.getView().getGroup();

            // xxx: hack
            if (myGroup != null) {
                PeerGroup myPeerGroup = myGroup.getPeerGroup();

                // xxx: 'nuther hack ... prefs needs a bath
                int shellStart = myPeerGroup != null ?
                        myPeerGroup.startApp(null) : -1;

                if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
                    LOG.fine("shellStart = " + shellStart);
                }
            }
        } else {
            if (wasEnabled) {
                myjxta.setStatus(STRINGS.getString("status.prefs.shell"));
                Group myGroup = myjxta.getView().getGroup();
                PeerGroup myPeerGroup = null;

                if (myGroup != null) {
                    myPeerGroup = myGroup.getPeerGroup();
                    /*
                     * TODO:  Figure out how to shutdown and clean up shell so it can be restarted
                     *        without requiring MyJxta2 to be restarted first.
                     */
                    myPeerGroup.stopApp();
                }
            }
        }

        LOG.fine("End   enableShell(boolean)");
    }


    public Container getUI() {
        return new LegacyUI(this);
    }

    public void destroy() {
        // no writeback chnages needed since all modifications
    }

    protected void booleanPreferenceChanged(String preferenceName, boolean selected) {
        Boolean current = prefTable.get(preferenceName);

        if (current.booleanValue() != selected) {
            prefTable.put(preferenceName, Boolean.valueOf(selected));
            this.setPreferece(preferenceName, String.valueOf(selected));
            if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
                LOG.fine("preferenceChanged " + preferenceName + "  " + selected);
            }
            // avoid using switch or ternary
            Method method = methodTable.get(preferenceName);
            Object[] params = {selected};
            try {
                method.invoke(this, params);
                LOG.fine("enable " + preferenceName + " " + selected);
            } catch (IllegalArgumentException ex) {
                ex.printStackTrace();
            } catch (IllegalAccessException ex) {
                ex.printStackTrace();
            } catch (InvocationTargetException ex) {
                ex.getCause().printStackTrace();
                ex.printStackTrace();
            }
        }
    }

}
